Skip to content

fix(search): show freeform genre as a selected filter chip#14489

Merged
dylanjeffers merged 1 commit into
mainfrom
fix/freeform-genre-search-filter-chip
Jun 17, 2026
Merged

fix(search): show freeform genre as a selected filter chip#14489
dylanjeffers merged 1 commit into
mainfrom
fix/freeform-genre-search-filter-chip

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

Problem

Clicking a freeform/custom genre (e.g. "Hyperpop Fusion") on a track page navigates to search, but the genre doesn't appear as a selected filter chip — leaving no indication of what's being filtered and making it unclear whether the search is filtering by that genre at all.

Root cause

The genre is read from the URL and is passed to the search API (useSearchResults.ts:177genre: filters.genre ? [filters.genre] : undefined), so server-side filtering already works.

The bug is purely in the filter UI. The harmony FilterButton resolves its active label by matching the URL genre value against its options, which are built from the ~51 hardcoded GENRES:

const selectedOption = options?.find((option) => option.value === value)
const selectedLabel = selectedOption?.label ?? selectedOption?.value
// ...
{selectedLabel ? renderLabel(selectedLabel) : label}

A freeform genre matches no option → selectedLabel is undefined → the chip falls back to the generic "Genre" label.

Fix

In the GenreFilter on both web and mobile, when the active genre isn't in the predefined GENRES list, add it as an option so the FilterButton can resolve a label and render it as a selected chip.

  • packages/web/src/pages/search-page/SearchFilters.tsx
  • packages/mobile/src/screens/search-screen/SearchFilters.tsx

No change needed on the API side — the genre was already passed through correctly.

Testing

  • eslint clean on both changed files
  • tsc --noEmit passes for both packages/web and packages/mobile

🤖 Generated with Claude Code

Clicking a freeform/custom genre (e.g. "Hyperpop Fusion") on a track
page navigates to search and the genre IS passed to the search API, but
the genre filter chip showed no indication of what was being filtered.

The FilterButton resolves its active label by matching the URL genre
value against its options, which are built from the ~51 hardcoded GENRES.
A freeform genre matches nothing, so selectedLabel is undefined and the
chip falls back to the generic "Genre" text.

Add the current genre as an option when it isn't in the predefined list
so it renders as a selected chip on both web and mobile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 17, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 6094140

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dylanjeffers dylanjeffers merged commit fa66a25 into main Jun 17, 2026
3 checks passed
@dylanjeffers dylanjeffers deleted the fix/freeform-genre-search-filter-chip branch June 17, 2026 00:33
@github-actions

Copy link
Copy Markdown
Contributor

🌐 Web preview ready

Preview URL: https://audius-web-preview-pr-14489.audius.workers.dev

Unique preview for this PR (deployed from this branch).
Workflow run

dylanjeffers added a commit that referenced this pull request Jun 18, 2026
… section (#14497)

## What

Replaces the hardcoded trending genre list with the **top genres ranked
by recent activity**, fetched dynamically from `/v1/genres/popular`.
This is needed now that freeform genres are supported and a static list
is no longer sufficient.

## Changes

**New hook — `usePopularGenres`**
(`packages/common/src/api/tan-query/search/usePopularGenres.ts`)
- Fetches the top 25 genres from `/v1/genres/popular`
- `staleTime` ~15 min to match the backend cache TTL
- Merges the ranked genres with the static list (deduped, popular-first)
so ranked genres carry a `count` and the long-tail stays searchable

**Trending genre filter — top genres by default + search for long-tail**
- Web desktop (`TrendingPageContent.tsx`): `FilterButton` options come
from the popular genres, with `showFilterInput` enabled so long-tail
genres are searchable
- Web mobile genre page (`GenreSelectionList` gains a `topGenres` prop):
shows the ranked genres by default, searches the full set
- Native mobile drawer (`TrendingFilterDrawer.tsx`): same top-by-default
+ search-the-long-tail behavior

**Freeform-safe selection** — new `toTrendingGenreValue` helper accepts
community/freeform genres (unlike `toTrendingGenre`, which dropped any
value outside the static `GENRES` list, nullifying freeform selections).
Builds on the freeform chip fix from #14489 without regressing it.

**Explore "Trending Genres" section** (web + mobile) and edit-track
genre suggestions are powered by the same hook.

## Notes / scope
- SDK genre endpoint (`GenresApi`, `PopularGenre`,
`PopularGenresResponse`) and wiring are included as a dependency.
- Unrelated SDK regen drift (Notification/Event/etc.) and the
comment-drawer work on the original branch were intentionally
**excluded** to keep this PR focused.
- Sharing a freeform genre via the trending URL param still won't
restore on reload (`isValidGenre` only validates the static list) —
in-session selection works; URL restore for freeform genres is left as a
follow-up.

## Test plan
- `tsc` passes for `common`, `web`, `mobile`
- `eslint` passes for all touched files
- `genres.test.ts` unit tests pass

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant